<template>
  <div :id="id"></div>
</template>

<script lang="ts">
import { defineComponent, onMounted, PropType, ref } from 'vue'
import G6 from '@antv/g6'
import { IModel } from '@/render/store/configdef/types'

export default defineComponent({
  props: {
    id: {
      type: String,
      required: true
    },
    treeData: {
      type: Object as PropType<IModel>,
      default: () => ({})
    }
  },
  setup(props) {
    // 1. 处理图的数据
    // const data = ref({ ...props.treeData }).value

    const data = JSON.parse(JSON.stringify(props.treeData))

    // 2. 注册结点样式
    G6.registerNode('card-node', {
      draw(cfg: any, group: any) {
        const r = 2
        let color
        let description = ''
        switch (cfg.type_) {
          case 'parameter':
            color = '#67c23a'
            description += `defaultValue = ${cfg.defaultValue}`
            if (
              cfg.parameterType === 'interger' ||
              cfg.parameterType === 'float'
            ) {
              description = `min = ${cfg.min}
max = ${cfg.max}`
            }
            break
          case 'reference':
            color = '#e6a23c'
            break
          case 'literal':
            color = '#f56c6c'
            break
          case 'destination':
            color = '#909399'
            break
          default:
            color = '#409eff'
            description = `upperMultiplicity = ${cfg.upperMultiplicity}
lowerMultiplicity = ${cfg.lowerMultiplicity}`
        }

        const w = cfg.size[0]
        const h = cfg.size[1]
        const shape = group.addShape('rect', {
          attrs: {
            x: -w / 2,
            y: -h / 2,
            width: w, //200,
            height: h, // 60
            stroke: color,
            radius: r,
            fill: '#fff'
          },
          name: 'main-box',
          draggable: true
        })

        group.addShape('rect', {
          attrs: {
            x: -w / 2,
            y: -h / 2,
            width: w, //200,
            height: h / 2, // 60
            fill: color,
            radius: [r, r, 0, 0]
          },
          name: 'title-box',
          draggable: true
        })

        // title text
        group.addShape('text', {
          attrs: {
            textBaseline: 'top',
            x: -w / 2 + 8,
            y: -h / 2 + 4,
            lineHeight: 20,
            text: `${cfg.label}
(${cfg.type_})`,
            fill: '#fff'
          },
          name: 'title'
        })
        cfg.children &&
          group.addShape('marker', {
            attrs: {
              x: w / 2,
              y: 0,
              r: 6,
              cursor: 'pointer',
              symbol: G6.Marker.collapse,
              stroke: '#666',
              lineWidth: 1,
              fill: '#fff'
            },
            name: 'collapse-icon'
          })
        group.addShape('text', {
          attrs: {
            textBaseline: 'top',
            x: -w / 2 + 8,
            y: -h / 2 + 24,
            lineHeight: 20,
            text: description,
            fill: 'rgba(0,0,0, 1)'
          },
          name: `description`
        })
        return shape
      },
      setState(name, value, item: any) {
        if (name === 'collapsed') {
          const marker = item
            .get('group')
            .find((ele: any) => ele.get('name') === 'collapse-icon')
          const icon = value ? G6.Marker.expand : G6.Marker.collapse
          marker.attr('symbol', icon)
        }
      }
    })

    // 3. 画图
    const drawGraph = () => {
      const toolbar = new G6.ToolBar({
        position: { x: 10, y: 72 }
      })

      const container = document.getElementById(`${props.id}`)
      const width = container?.scrollWidth
      const height = container?.scrollHeight || 655
      const graph = new G6.TreeGraph({
        container: container || `${props.id}`,
        width,
        height,
        plugins: [toolbar],
        modes: {
          default: ['drag-canvas']
        },
        defaultNode: {
          type: 'card-node',
          size: [160, 80]
        },
        defaultEdge: {
          type: 'cubic-horizontal',
          style: {
            endArrow: true
          }
        },
        layout: {
          type: 'indented',
          direction: 'LR',
          dropCap: false,
          indent: 200,
          getHeight: () => {
            return 60
          }
        }
      })

      graph.data(data)
      graph.render()
      graph.fitView()

      // 绑定结点事件
      graph.on('node:click', (e: any) => {
        if (e.target.get('name') === 'collapse-icon') {
          e.item.getModel().collapsed = !e.item.getModel().collapsed
          graph.setItemState(e.item, 'collapsed', e.item.getModel().collapsed)
          graph.layout()
        }
      })
      graph.on('node:contextmenu', (e: any) => {
        const type = e.item._cfg.model.type_
        console.log(type)
      })

      if (typeof window !== 'undefined') {
        window.onresize = () => {
          if (!graph || graph.get('destroyed')) return
          if (!container || !container.scrollWidth || !container.scrollHeight)
            return
          graph.changeSize(container.scrollWidth, container.scrollHeight)
        }
      }
    }

    onMounted(() => {
      drawGraph()
    })

    return {}
  }
})
</script>

<style scoped lang="less"></style>
